int n,m; //n是点数，m是边数
int fa[N]; //并查集的父节点数组

struct Edge//存储边
{
    int a,b,w; 

    bool operator<(const Edge& W)const
    {
        return w<W.w; 
    }
}edges[M]; 

int find(int x)//并查集核心操作
{
    if(fa[x]!=x)fa[x]=find(fa[x]); 
    return fa[x]; 
}

int kruskal()
{
    sort(edges,edges+m); 

    for(int i=1; i<=n; i++)fa[i]=i; //初始化并查集

    int res=0,cnt=0; 
    for(int i=0; i<m; i++)
    {
        int a=edges[i].a,b=edges[i].b,w=edges[i].w; 

        a=find(a),b=find(b); 
        if(a!=b)//如果两个连通块不连通，则将这两个连通块合并
        {
            fa[a]=b; 
            res+=w; 
            cnt++; 
        }
    }

    if(cnt<n-1)return INF; 
    return res; 
}
